package com.hmdp.utils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.hmdp.entity.Shop;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
 * @package: com.hmdp.utils
 * @className: CacheClientNew
 * @author: 云溪
 * @description:
 * @date: 2025/9/8 20:05
 * @version: 1.0
 */
@Component
public class CacheClientNew {

    @Resource
    StringRedisTemplate stringRedisTemplate;

    /**
     * 只解决缓存穿透
     * @param id
     * @return
     */
    public <R,ID> R queryWithPassThrough(
            String keyPrefix, ID id, Class<R> type, Function<ID,R> dbFallback, Long time, TimeUnit unit){
        // 1. 从Redis查询商铺缓存
        String rJson = stringRedisTemplate.opsForValue().get(keyPrefix + id);

        // 2. 判断缓存中是否存在
        if (StrUtil.isNotBlank(rJson)) {
            // 3. 存在，直接返回
            R r = JSONUtil.toBean(rJson, type);
            return r;
        }

        // 4. 判断命中的是否是空值
        if("".equals(rJson)){
            return null;
        }

        // 4. 不存在，根据id查询数据库
        R r = dbFallback.apply(id);

        // 5. 不存在，返回错误，将空值写入Redis
        if (null == r) {
            stringRedisTemplate.opsForValue().set(keyPrefix + id, "",
                    RedisConstants.CACHE_NULL_TTL, TimeUnit.MINUTES);
            return null;
        }
        // 6. 存在，写入Redis
        stringRedisTemplate.opsForValue().set(keyPrefix +id, JSONUtil.toJsonStr(r),
                time, unit);

        return r;
    }


}
